package com.edu.admin.common;

import java.lang.reflect.ParameterizedType;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.edu.admin.utils.EntityUtils;
import com.edu.admin.utils.Query;
import com.github.pagehelper.PageHelper;

import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.mapperhelper.EntityHelper;

/**
 * 业务逻辑基类
 * 
 * 
 */
public abstract class BaseService<M extends BaseMapper<T>, T> {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	protected M mapper;

	public void setMapper(M mapper) {
		this.mapper = mapper;
	}

	/**
	 * 查询一个对象
	 *
	 * @param entity
	 * @return
	 */
	public T selectOne(T entity) {
		return mapper.selectOne(entity);
	}

	/**
	 * 按删除标记 和主键ID查询对象
	 *
	 * @param id
	 * @return
	 *
	 */
	@SuppressWarnings("unchecked")
	public T selectByPrimaryKeyIsUse(Object id) {
		Class<T> entity = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
				.getActualTypeArguments()[1];
		Set<EntityColumn> columnSet = EntityHelper.getPKColumns(entity);
		if (columnSet.size() == 1) {
			Example example = new Example(entity);
			Example.Criteria criteria = example.createCriteria();
			Iterator<EntityColumn> it = columnSet.iterator();
			while (it.hasNext()) {
				EntityColumn column = it.next();
				criteria.andEqualTo(column.getEntityField().getName(), id);
			}
			criteria.andEqualTo("useType", 0);
			List<T> list = mapper.selectByExample(example);
			if (list.size() == 1) {
				return list.get(0);
			}
		}
		return null;
	}

	/**
	 * 按主键ID查询对象
	 *
	 * @param id
	 * @return
	 *
	 */
	public T selectByPrimaryKey(Object id) {
		return mapper.selectByPrimaryKey(id);
	}

	/**
	 * 按可用标记，查询对象列表
	 *
	 * @param entity
	 * @return
	 *
	 */
	public List<T> selectListIsUse(T entity) {
		EntityUtils.setUse(entity);
		return mapper.select(entity);
	}
	
	/**
	 * 按可用标记，查询对象列表
	 *
	 * @param entity
	 * @return
	 *
	 */
	public List<T> selectListIsNotUse(T entity) {
		EntityUtils.setNotUse(entity);
		return mapper.select(entity);
	}

	/**
	 * 查询对象列表
	 *
	 * @param entity
	 * @return
	 *
	 */
	public List<T> selectList(T entity) {
		return mapper.select(entity);
	}

	/**
	 * 查询所有对象
	 *
	 * @return
	 *
	 */
	public List<T> selectListAll() {
		return mapper.selectAll();
	}

	/**
	 * 按可用标记查询所有对象
	 *
	 * @return
	 *
	 */
	@SuppressWarnings("unchecked")
	public List<T> selectListAllIsUse() {
		Class<T> entity = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
				.getActualTypeArguments()[1];
		Example example = new Example(entity);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("useType", 0);
		return mapper.selectByExample(example);
	}

	/**
	 * 按可用标记查询记录数
	 *
	 * @param entity
	 * @return
	 *
	 */
	public Long selectCountIsUse(T entity) {
		EntityUtils.setUse(entity);
		return new Long(mapper.selectCount(entity));
	}
	
	/**
	 * 按可用标记查询记录数
	 *
	 * @param entity
	 * @return
	 *
	 */
	public Long selectCountIsNotUse(T entity) {
		EntityUtils.setNotUse(entity);
		return new Long(mapper.selectCount(entity));
	}

	/**
	 * 查询记录数
	 *
	 * @param entity
	 * @return
	 *
	 */
	public Long selectCount(T entity) {
		return new Long(mapper.selectCount(entity));
	}


	/**
	 * 保存
	 *
	 * @param entity
	 *
	 */
	public int insert(T entity) {
		EntityUtils.setCreatAndUpdatInfo(entity);
		return mapper.insert(entity);
	}

	
	/**
	 * 批量保存对象，仅支持mysql
	 *
	 * @param recordList
	 *
	 */
	public int insertList(List<T> recordList) {
		for (T entity : recordList) {
			EntityUtils.setCreatAndUpdatInfo(entity);
		}
		return mapper.insertList(recordList);
	}

	/**
	 * 保存不自动设置ID;保存一个实体，null的属性不会保存，会使用数据库默认值
	 *
	 * @param entity
	 *
	 */
	public int insertSelectiveNoId(T entity) {
		EntityUtils.setCreatAndUpdatInfo(entity);
		return mapper.insertSelective(entity);
	}


	/**
	 * 保存不自动设置ID;保存一个实体，null的属性不会保存，会使用数据库默认值
	 *
	 * @param entity
	 *
	 */
	public int insertSelective(T entity) {
		EntityUtils.setCreatAndUpdatInfo(entity);
		return mapper.insertSelective(entity);
	}

	/**
	 * 删除对象
	 *
	 * @param entity
	 *
	 */
	public int delete(T entity) {
		return mapper.delete(entity);
	}

	/**
	 * 启用
	 *
	 * @param entity
	 *
	 */
	public int setUse(T entity) {
		EntityUtils.setUse(entity);
		return mapper.updateByPrimaryKey(entity);
	}

	/**
	 * 启用
	 *
	 * @param entity
	 *
	 */
	public void setUseList(T entity) {
		List<T> list = selectList(entity);
		for (T t : list) {
			EntityUtils.setUse(entity);
			mapper.updateByPrimaryKey(t);
		}
	}
	
	/**
	 * 停用
	 *
	 * @param entity
	 *
	 */
	public int setNotUse(T entity) {
		EntityUtils.setNotUse(entity);
		return mapper.updateByPrimaryKey(entity);
	}

	/**
	 * 停用
	 *
	 * @param entity
	 *
	 */
	public void setNotUseList(T entity) {
		List<T> list = selectList(entity);
		for (T t : list) {
			EntityUtils.setNotUse(entity);
			mapper.updateByPrimaryKey(t);
		}
	}

	/**
	 * 按主键删除对象
	 *
	 * @param id
	 *
	 */
	public int deleteByPrimaryKey(Object id) {
		return mapper.deleteByPrimaryKey(id);
	}


	/**
	 * 更新对象，所有字段更新
	 *
	 * @param entity
	 *
	 */
	public int updateByPrimaryKey(T entity) {
		EntityUtils.setUpdatedInfo(entity);
		return mapper.updateByPrimaryKey(entity);
	}

	/**
	 * 更新对象，根据主键更新属性不为null的值
	 *
	 * @param entity
	 *
	 */
	public int updateByPrimaryKeySelective(T entity) {
		EntityUtils.setUpdatedInfo(entity);
		return mapper.updateByPrimaryKeySelective(entity);

	}

	/**
	 * 模糊查询
	 *
	 * @param query
	 * @return
	 *
	 */
	@SuppressWarnings("unchecked")
	public List<T> selectByQuery(Query query) {
		Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
		Example example = new Example(clazz);
		Example.Criteria criteria = example.createCriteria();
		for (Map.Entry<String, Object> entry : query.entrySet()) {
			criteria.andLike(entry.getKey(), "%" + entry.getValue().toString() + "%");
		}
		PageHelper.startPage(query.getPage(), query.getLimit());
		List<T> list = mapper.selectByExample(example);
		return list;
	}


}
